package com.shoping.web.component.processor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Constructor;

/**
 * predictBeanType:该触发点发生在postProcessBeforeInstantiation之前(在图上并没有标明，因为一般不太需要扩展这个点)，这个方法用于预测
 * Bean 的类型，返回第一个预测成功的 Class 类型，如果不能预测返回 null；当你调用BeanFactory.getType(name)时当通过 test 的名字无法得
 * 到 test 类型信息时就调用该回调方法来决定类型信息。
 * <p>
 * determineCandidateConstructors：该触发点发生在postProcessBeforeInstantiation之后，用于确定该 test 的构造函数之用，返回的是该
 * test 的所有构造函数列表。用户可以扩展这个点，来自定义选择相应的构造器来实例化这个 test。
 * <p>
 * getEarlyBeanReference：该触发点发生在postProcessAfterInstantiation之后，当有循环依赖的场景，当 test 实例化好之后，为了防止有循
 * 环依赖，会提前暴露回调方法，用于 test 实例化的后置处理。这个方法就是在提前暴露的回调方法中触发。
 */
@Slf4j
@Configuration
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {

    @Override
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
        return beanClass;
    }

    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
